package com.lh.glassmuseum.util;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.lh.glassmuseum.config.AppConfig;
import com.lh.glassmuseum.service.ImageService;
import com.lh.glassmuseum.service.SerialPortService;
import com.lh.glassmuseum.service.TipService;
import org.apache.commons.codec.digest.DigestUtils;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.security.Key;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.util.*;

public class UrlSignUtil {

    /**
     * 19 * 请求参数加签（签名）
     * 20 *
     * 21 * @param params 参数
     * 22 * @param token token
     * 23 * @return String
     * 24
     */
    public static String paramSign(Map<String, String> params, String token) {
        SortedMap<String, String> sortedMap = new TreeMap<>(params);

        StringBuilder toSign = new StringBuilder();
        for (String key : sortedMap.keySet()) {
            String value = params.get(key);
            boolean shouldSign = false;
            if (null != value && !Objects.equals("sign",key)) {
                shouldSign = true;
            }
            if (shouldSign) {
                toSign.append(key).append("=").append(value).append("&");
            }
        }

        toSign.append("token=").append(token);
        return DigestUtils.sha1Hex(toSign.toString()).toUpperCase();
    }

    /**
     * 45 * AES加密
     * 46 *
     * 47 * @param plainText 普通文本
     * 48 * @param cdKey 加密密钥，长度可随意指定
     * 49 * @return String
     * 50 * @throws Exception 异常
     * 51
     */
    public static String encode(String plainText, String cdKey) throws Exception {
        Key key = new SecretKeySpec(cdKey.getBytes(StandardCharsets.UTF_8), "AES");
        //加密
        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, key);

        byte[] encryptData = cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8));
        return new String(Base64.getEncoder().encode(encryptData));
    }

    /**
     62 * AES解密
     63 *
     64 * @param encryptText 加密文本
     * @param cdKey 解密密钥，长度可随意指定
    66 * @return String
    67 * @throws Exception 异常
    68 */
    public static String decode(String encryptText, String cdKey) throws Exception {
        Key key = new SecretKeySpec(cdKey.getBytes(StandardCharsets.UTF_8), "AES");
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, key);
        byte[] decryptData = cipher.doFinal(Base64.getDecoder().decode(encryptText));
        return new String(decryptData, StandardCharsets.UTF_8);
    }

    public static void main(String[] args) {
        Map<String, String> params = new HashMap<>();
        String timestamp = String.valueOf(System.currentTimeMillis());
        String nonce = getCurrTime()+buildRandom(4);
//        params.put("token", "VhW96rEKZw6KtY8St2ItihQcGjvYxPkP");
        params.put("chanType","1");
        params.put("chanCode","ZJ005");
        params.put("codeType","1");
        params.put("code","N3ZdQc1AtJ12");
        params.put("appId", AppConfig.appId);
        params.put("timestamp", timestamp);
        params.put("nonce",nonce);
        String sign = paramSign(params,AppConfig.token);
        Map<String,String> jsonObject = new HashMap<>();
        jsonObject.put("appId",AppConfig.appId);
        jsonObject.put("timestamp",timestamp);
        jsonObject.put("nonce",nonce);
        jsonObject.put("sign",sign);
        String xsign;
        try {
            xsign = encode(JSON.toJSONString(jsonObject),AppConfig.aesKey);
        } catch (Exception e) {
            e.printStackTrace();
            return;
        }
        HttpClient client = HttpClient.newBuilder()
                .connectTimeout(Duration.ofSeconds(10))
                .version(HttpClient.Version.HTTP_2)
                .build();
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(AppConfig.url+"N3ZdQc1AtJ12"))
                .header("Content-Type", "application/json")
                .header("Accept", "application/json")
                .header("X-AUTH-SIGN", xsign)
                .POST(HttpRequest.BodyPublishers.ofString("{}"))
                .build();
        try {
            HttpResponse<String> rep = client.send(request, HttpResponse.BodyHandlers.ofString());
//            GlassResult result = JSONObject.parseObject(rep.body(),GlassResult.class);
            System.out.println(rep.body());
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
    }


    public static String getCurrTime() {
        return new SimpleDateFormat("yyyyMMdd").format(new Date());
    }

    public static int buildRandom(int length) {
        int num = 1;
        double random = Math.random();
        if (random < 0.1) {
            random = random + 0.1;
        }
        for (int i = 0; i < length; i++) {
            num = num * 10;
        }
        return (int) ((random * num));
    }
}
